﻿using System;
using System.Collections.Generic;
using System.Threading;
using CommonTypes.Server;
using Server.Model;

namespace Server.Services.Primary
{
    public class PrimaryPingController : PingManager
    {
        private delegate void StartBully( ServerData serverData );

        public override void executePingTimer( object args )
        {
            KeyValuePair<AutoResetEvent, ServerData> argPair = ( KeyValuePair<AutoResetEvent, ServerData> )args;
            AutoResetEvent ev = argPair.Key;
            ServerData serverData = argPair.Value;

            if( serverData.State == ServerState.ESTABLISHED )
            {
                ImAliveResponse resp = ImAliveResponse.OK;

                System.Console.WriteLine( "I'm sending a ping!" );

                foreach( KeyValuePair<String, IServerToServer> servers in serverData.ServersInformation.ServersProxy )
                {
                    if( BullyProtocol.getServerIdNumber( serverData.ServerId ) > BullyProtocol.getServerIdNumber( servers.Key ) )
                        continue;
                    if( !servers.Key.Equals( serverData.ServerId ) && serverData.ServersInformation.ActiveServers[ servers.Key ] )
                    {
                        try
                        {
                            resp = servers.Value.ImAlive( serverData.ServerId, serverData.ServerLogicalClock );
                            System.Console.WriteLine( String.Format( "Server {0} response is {1}", servers.Key, resp ) );
                            if( resp == ImAliveResponse.PRIMARY_UNKNOWN )
                                break;
                        }
                        catch
                        {
                            System.Console.WriteLine( String.Format( "Server {0} is down!", servers.Key ) );
                            serverData.ServersInformation.ActiveServers[ servers.Key ] = false;
                            continue;
                        }
                    }
                }

                if( resp == ImAliveResponse.PRIMARY_UNKNOWN )
                {
                    System.Console.WriteLine( "Someone does not recognizes me as a primary, so I'm going to start bullying..." );
                    ev.Set( );
                }
            }
        }
    }
}